/*
 * **.cpp - 
 *
 * Copyright (C) 2010-2012 Serge Begger
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "cueparser.h"

cueparser::cueparser(QObject *parent) :
    QObject(parent)
{
}

bool cueparser::parse(QString filename) {
    QString m_filename = filename;
    int year = 0; QString album = "";
    QFileInfo fi(m_filename);
    if (fi.exists() && (fi.suffix() == "flac" || fi.suffix() == "ape")) {
        QFile file;
        file.setFileName(m_filename.replace("."+fi.suffix(),".cue"));
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qWarning("Unable to open cue file!");
            return false;
        }
        QTextStream stream(file.readAll().data());
        stream.setCodec("UTF-8");
        file.close();
        while(!stream.atEnd()) {
            QString line = stream.readLine().trimmed();
            QStringList wordsList = splitLine(line);
            if (wordsList.size() < 2)
                continue;
            if (wordsList.size() > 2) {

            }
            if(wordsList.at(0) == "REM") {
                if(wordsList.at(1) == "DATE")
                    year = wordsList.at(2).toInt();
            } else if(wordsList.at(0) == "TITLE") {
                if (trackList.isEmpty())
                    album = wordsList.at(1);
                else
                    trackList.last().Title = wordsList.at(1);
            } else if(wordsList.at(0) == "PERFORMER" && !trackList.isEmpty()) {
                trackList.last().Artist = wordsList.at(1);
            } else if(wordsList.at(0) == "TRACK") {
                track currTrack;
                trackList.append(currTrack);
            } else if(wordsList.at(0) == "INDEX" && wordsList.at(1) == "01") {
                if (trackList.isEmpty())
                    continue;
                trackList.last().Album = album;
                trackList.last().Year = year;
                trackList.last().Start = getFrame(wordsList.at(2));
                int t = trackList.count();
                if(t > 1) {
                    track prevtrack = trackList.at(t-2);
                    prevtrack.Lenght = trackList.last().Start - prevtrack.Start - 1;
                    trackList.removeAt(t-2); trackList.insert(t-2,prevtrack);
                }
            }
        }
        return true;
    }
    return false;
}

QStringList cueparser::splitLine(const QString &line)
{
    QStringList list;
    QString buf = line.trimmed();
    if (buf.isEmpty())
        return list;
    while (!buf.isEmpty())
    {
        if (buf.startsWith('"'))
        {
            int end = buf.indexOf('"',1);
            list << buf.mid (1, end - 1);
            buf.remove (0, end+1);
        }
        else
        {
            int end = buf.indexOf(' ', 0);
            if (end < 0)
                end = buf.size();
            list << buf.mid (0, end);
            buf.remove (0, end);
        }
        buf = buf.trimmed();
    }
    return list;
}

qint64 cueparser::getFrame(QString msf) {
    QStringList sym =  msf.split(":");
    if(sym.count() < 3) return 0;
    return msf_to_frame( sym.at(0).toInt(), sym.at(1).toInt(), sym.at(2).toInt());
}

qint64 cueparser::msf_to_frame(int m, int s, int f)
{
        return (m * 60 + s) * 75 + f;
}

void cueparser::frame_to_msf(qint64 frame, int *m, int *s, int *f)
{
        *f = frame % 75;
        frame /= 75;
        *s = frame % 60;
        frame /= 60;
        *m = frame;
}
